package mips.instructions;

/**
 * <code>MFHI</code> instruction<br/>
 * Move From HI<br/>
 * @author jnmartin84@gmail.com
 */
public class MFHI extends Instruction {

	private static final MFHI INSTANCE = new MFHI();
	private static final String INSTRUCTION_NAME = "MFHI";

	private MFHI(){}

	public static final MFHI getInstance() {
		return INSTANCE;
	}

	/**
	 * <b>Format:</b><br/>
	 * MFHI rd<br/><br/>
	 * <b>Description:</b><br/>
	 * The contents of special register HI are loaded into general register rd.<br/><br/>
	 * To ensure proper operation in the event of interruptions, the two<br/>
	 * instructions which follow a MFHI instruction may not be any of the<br/>
	 * instructions which modify the HI register: MULT, MULTU, DIV, DIVU,<br/>
	 * MTHI, DMULT, DMULTU, DDIV, DDIVU.<br/><br/>
	 * <b>Operation:</b><br/>
	 * T: GPR[rd] &larr; HI<br/>
	 */
	@Override
	public final void execute(final int instruction) {

		mips.instructions.Instruction.RD = (instruction >> 11) & 0x0000001F;

		mips.R4300i.GPR[mips.instructions.Instruction.RD] = mips.R4300i.HI;

		mips.R4300i.PC = mips.R4300i.nPC;
		mips.R4300i.nPC = mips.R4300i.PC + 4;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String emit(final int instruction) {

		mips.instructions.Instruction.RD = (instruction >> 11) & 0x0000001F;

		return	"		mips.CPU.GPR["+mips.instructions.Instruction.RD+"] = mips.CPU.HI;\n" +
				"		\n" +
				"		mips.CPU.PC = mips.CPU.nPC;\n" +
				"		mips.CPU.nPC = mips.CPU.PC + 4;\n";
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName(final int instruction) {
		return getName();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public final String getName() {
		return INSTRUCTION_NAME;
	}
}